/*
 * Lock_Lock_Function_new_Pool.h
 *
 *  Created on: 2014. 6. 24.
 *      Author: jjaehuny
 */

#ifndef FRAMEWORK_MEMORY_LOCK_LOCK_FUNCTION_NEW_POOL_H_
#define FRAMEWORK_MEMORY_LOCK_LOCK_FUNCTION_NEW_POOL_H_

#include <mutex>

#include <glog/logging.h>

#include "Base_Pool.h"

namespace Framework { namespace Memory {

template<class Type>
class Lock_Function_new_Pool : public Base_Pool<Type>
{
public:
	Lock_Function_new_Pool (bool bPost = false, unsigned long pool_size = 1);
	virtual ~Lock_Function_new_Pool ();

protected:
	virtual Type * allocator ();
	virtual void deleter (Type * pType);

private:
	std::mutex mutex_;

};

template<class Type>
Lock_Function_new_Pool<Type>::Lock_Function_new_Pool (bool bPost, unsigned long pool_size) : Base_Pool<Type>(bPost, pool_size)
{

}

template<class Type>
Lock_Function_new_Pool<Type>::~Lock_Function_new_Pool ()
{

}

template<class Type> Type *
Lock_Function_new_Pool<Type>::allocator ()
{
	LOG(INFO) << __PRETTY_FUNCTION__;

	Type * pType = NULL;
	{
		std::lock_guard<std::mutex> lo(mutex_);
		if (true != Base_Pool<Type>::type_deque_.empty())
		{
			pType = Base_Pool<Type>::type_deque_.front();
			Base_Pool<Type>::type_deque_.pop_front();
		}
	}

	// call func
	if (NULL != pType)
	{
		pType->Initialize();
	}
	else
	{
		pType = new Type;
		pType->Initialize();
	}

	return pType;
}

template<class Type> void
Lock_Function_new_Pool<Type>::deleter (Type * pType)
{
	if (NULL != pType)
	{
		// call func
		pType->Finalize();

		LOG(INFO) << __PRETTY_FUNCTION__;

		{
			std::lock_guard<std::mutex> lo(mutex_);
			Base_Pool<Type>::type_deque_.push_back(pType);
		}
	}
}

} /*Memory*/ } /*Framework*/


#endif /* FRAMEWORK_MEMORY_LOCK_LOCK_FUNCTION_NEW_POOL_H_ */
